#pragma once 
#include<iostream>
#include<cstring>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<strings.h>
#include<arpa/inet.h>
#include<unistd.h>

using namespace std;
uint16_t defaultport=8080;
string defaultip="0.0.0.0";
 const int sz=1024;

class udpserver
{
public:
   udpserver(const uint16_t &port=defaultport,const string &ip=defaultip)
   :sockfd_(0)
   ,port_(port)
   ,ip_(ip)
   ,isrunning_(false)
  {}
  void init()
  { 
   sockfd_=socket(AF_INET,SOCK_DGRAM,0);
   if(sockfd_<0)
    {
      cout<<"创建网络套接字失败"<<endl;
      exit(1);
    }
    cout<<"创建网络套接字成功"<<endl;

    struct sockaddr_in local;
    bzero(&local,sizeof(local));
    local.sin_family=AF_INET;
    local.sin_port=htons(port_);
    local.sin_addr.s_addr=inet_addr(ip_.c_str());
    
    if(bind(sockfd_,(const struct sockaddr*)&local,sizeof(local))<0)
      {cout<<"绑定失败"<<endl;
       exit(1);
      }

      cout<<"绑定成功"<<endl;
  }

  
  void run()
  {
  isrunning_=true;
 
  char inbuffer[sz];
  while(isrunning_)
       {
       struct sockaddr_in client;
       socklen_t len =sizeof(client);
       ssize_t n=recvfrom(sockfd_,inbuffer,sizeof(inbuffer)-1,0,(struct sockaddr*)&client,&len);
       if(n<0)
       {
         cout<<"客户端接收失败"<<endl;
         continue;
       }
       inbuffer[n]=0;
       string info=inbuffer;
       string addinfo="echo: "+info;
       cout<<addinfo<<endl;
       sendto(sockfd_,addinfo.c_str(),addinfo.size(),0,(const sockaddr*)&client,len);
       }
  }
~udpserver()
{


if(sockfd_>0) close(sockfd_);



}
private:
 int sockfd_;
 string ip_;
 uint16_t port_;
 bool isrunning_;

};